package com.vast.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vast.admin.api.WechatApi;
import com.vast.admin.entity.Contract;
import com.vast.admin.entity.ContractRefund;
import com.vast.common.core.domain.entity.SysUser;
import com.vast.admin.mapper.ContractRefundMapper;
import com.vast.admin.service.ContractService;
import com.vast.system.exception.BusinessException;
import com.vast.system.utils.Constant;
import com.vast.system.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class ContractRefundServiceImpl extends ServiceImpl<ContractRefundMapper, ContractRefund> {

    @Autowired
    private ContractService contractService;

    @Autowired
    private WechatApi wechatApi;

    @Autowired
    private CompanyAccountService companyAccountService;

    /**
     * 退款申请
     * @param contractRefund
     * @param manager
     */
    public void refundApply(ContractRefund contractRefund, SysUser manager) {
        Contract contract = contractService.getById(contractRefund.getContractId());
        if (contract == null) {
            throw new BusinessException("合同不存在");
        }
        contractRefund.setContractNo(contract.getContractNo());
        contractRefund.setContractName(contract.getContractName());
        contractRefund.setAmount(contract.getContractAmount());
        contractRefund.setWechatNo(getRefundNo(contractRefund.getContractId()));
        contractRefund.setCreateBy(manager.getUserId());
        contractRefund.setCreateTime(new Date());
        contractRefund.setStatus("1");
        super.save(contractRefund);

        UpdateWrapper<Contract> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set(Contract.COL_IS_PAY, 2)
                .set(Contract.COL_UPDATE_TIME, new Date())
                .set(Contract.COL_UPDATE_BY, manager.getUserId())
                .eq(Contract.COL_ID, contractRefund.getContractId());
        contractService.update(updateWrapper);
    }

    /**
     * 审批退款申请
     * @param contractRefund
     * @param manager
     */
    @Transactional(rollbackFor = Exception.class)
    public void approveRefund(ContractRefund contractRefund, SysUser manager) {
        UpdateWrapper<ContractRefund> contractRefundUpdateWrapper = new UpdateWrapper<>();
        contractRefundUpdateWrapper.set(ContractRefund.COL_STATUS, contractRefund.getStatus())
                .set(ContractRefund.COL_COMMENT, contractRefund.getComment())
                .set(ContractRefund.COL_UPDATE_BY, manager.getUserId())
                .set(ContractRefund.COL_UPDATE_TIME, new Date())
                .eq(ContractRefund.COL_ID, contractRefund.getId());
        if ("2".equals(contractRefund.getStatus())) {
            Contract contract = contractService.getById(contractRefund.getContractId());
            //审核通过，确认退款
            if (StringUtils.isBlank(contract.getWechatNo())) {
                //企业预付账户
                companyAccountService.refund(contract, manager);
                contractService.changeIsPayByContractId(3, contractRefund.getContractId(), manager.getUserId());
                //取消合同
                contractService.cancelContract(contract, manager.getUserId());
                //设置状态为退款成功
                contractRefundUpdateWrapper.set(ContractRefund.COL_STATUS, 4);
            } else {
                //微信支付
                wechatRefund(contractRefund, manager);
                contractRefundUpdateWrapper.set(ContractRefund.COL_STATUS, 2);
            }
        } else if ("3".equals(contractRefund.getStatus())) {
            contractRefundUpdateWrapper.set(ContractRefund.COL_STATUS, contractRefund.getStatus());
            contractService.changeIsPayByContractId(4, contractRefund.getContractId(), manager.getUserId());
        } else {
            contractRefundUpdateWrapper.set(ContractRefund.COL_STATUS, contractRefund.getStatus());
        }
        super.update(contractRefundUpdateWrapper);
    }

    /**
     * 微信退款
     * @param contractRefund
     */
    private void wechatRefund(ContractRefund contractRefund, SysUser manager) {
        Contract contract = contractService.getById(contractRefund.getContractId());
        if (contract == null) {
            throw new BusinessException("合同不存在");
        }
        UpdateWrapper<Contract> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set(Contract.COL_IS_PAY, 2)
                .set(Contract.COL_UPDATE_BY, manager.getUserId())
                .set(Contract.COL_UPDATE_TIME, new Date())
                .eq(Contract.COL_ID, contract.getId());
        contractService.update(updateWrapper);
        //调用微信退款接口
        wechatApi.refund(contract.getWechatNo(), contractRefund.getWechatNo(), new Double(contractRefund.getAmount() * 100).longValue(), contractRefund.getApplyDesc());
    }

    /**
     * 微信退款成功回调
     * @param wechatNo
     */
    @Transactional
    public void wechatRefundCallback(String wechatNo) {
        ContractRefund contractRefund = getByWechatNo(wechatNo);
        if (contractRefund == null) {
            throw new BusinessException("退款单号【" + wechatNo + "】未查询到退款信息");
        }
        if ("4".equals(contractRefund.getStatus())) {
            log.warn("退款单号【{}】已退款", wechatNo);
            return;
        }
        Contract contract = contractService.getById(contractRefund.getContractId());
        if (contract.getIsPay() == 3) {
            log.warn("退款单号【{}】已退款", wechatNo);
            return;
        }
        contractService.cancelContract(contract, Constant.SUPER_ADMIN);
        contractService.changeIsPayByContractId(3, contractRefund.getContractId(), 0L);
        UpdateWrapper<ContractRefund> contractRefundUpdateWrapper = new UpdateWrapper<>();
        contractRefundUpdateWrapper.set(ContractRefund.COL_STATUS, 4)
                .set(ContractRefund.COL_UPDATE_TIME, new Date())
                .set(ContractRefund.COL_UPDATE_BY, Constant.SUPER_ADMIN)
                .eq(ContractRefund.COL_ID, contractRefund.getId());
        super.update(contractRefundUpdateWrapper);
    }

    /**
     * 微信退款单号获取
     * @param wechatNo
     * @return
     */
    public ContractRefund getByWechatNo(String wechatNo) {
        QueryWrapper<ContractRefund> contractRefundQueryWrapper = new QueryWrapper<>();
        contractRefundQueryWrapper.eq(ContractRefund.COL_WECHAT_NO, wechatNo);
        List<ContractRefund> contractRefunds = super.list(contractRefundQueryWrapper);
        if (contractRefunds != null && !contractRefunds.isEmpty()) {
            return contractRefunds.get(0);
        }
        return null;
    }

    /**
     * 获取退款订单号
     * @param contractId
     * @return
     */
    private String getRefundNo(Long contractId) {
        return "ZFW-REFUND-" + contractId + "-" + System.currentTimeMillis();
    }

}
